package com.cnap.multiclouldmgmt.config;



import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.cnap.multiclouldmgmt.model.CommonResult;
import com.cnap.multiclouldmgmt.model.ResultCode;
import com.cnap.multiclouldmgmt.util.CnapCloudMgmtConstants;
import com.cnap.multiclouldmgmt.util.JsonUtil;
import com.cnap.multiclouldmgmt.util.TokenUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * token校验
 *
 * @author xc
 * 过滤所有对前端的接口
 **/
@WebFilter(urlPatterns = {"/cnap/multicloudmgmt/v1/k8sCluster/*","/cnap/multicloudmgmt/v1/multiCloud/*", "/cnap" +
        "/multicloudmgmt/v1/scaling/*","/cnap/multicloudmgmt/v1/vm/*","/cnap/multicloudmgmt/v1/health/*"})
public class TokenFilter implements Filter {

    private final UserSysConfig userSysConfig;

    @Autowired
    public TokenFilter(UserSysConfig userSysConfig) {
        this.userSysConfig = userSysConfig;
    }

    private static final Logger LOGGER = LoggerFactory.getLogger(TokenFilter.class);

    /**
     * 过滤token
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //获取token
        String token = request.getHeader("Authorization");
        //获取token为空，或者检查失败就抛出401
        if (Objects.isNull(token) || !checkToken(token)
                || StringUtils.equals(token, CnapCloudMgmtConstants.TEST_ADMIN)) {
            LOGGER.error("token is invalid");

            HttpServletResponse response = (HttpServletResponse) servletResponse;
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            servletResponse.setContentType("application/json");
            servletResponse.setCharacterEncoding("utf-8");
            if (servletResponse.getWriter() != null) {
                servletResponse.getWriter().println(JsonUtil.objectToJsonStr(CommonResult.failed((int) ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage())));
            }
            return;
        }

        TokenUtils.setTOKEN(token);

        filterChain.doFilter(servletRequest, servletResponse);
    }

    private boolean checkToken(String token) {
        try {
            JWT jwt = JWT.of(token);
            int expTime = (int) jwt.getPayload("exp");
            if (expTime < System.currentTimeMillis() / 1000) {
                return false;
            }
            return jwt.setSigner(JWTSignerUtil.hs256(Base64Decoder.decode(userSysConfig.getSecret()))).verify();

        } catch (Exception e) {
            LOGGER.error("parse token error, {}", e.getMessage());
        }
        return false;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
